package com.ysh.steam;

import com.ysh.pojo.Item;
import com.ysh.pojo.Order;
import com.ysh.pojo.User;
import org.omg.CORBA.StringHolder;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 袁胜虎 on 2022/9/2 16:54
 */
public class StreamTest {
    public static void main(String[] args) {
        ArrayList<User> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            User user = new User();
            user.setName("小李"+i);
            user.setAge(23+i);
            user.setAddresss("北京市沙河市");
            list.add(user);
        }


        ArrayList<User> list1 = new ArrayList<>();
        for (User user: list) {
            int age = user.getAge();
            if (age >= 25){
                list1.add(user);
            }
        }

        //stream的核心思想,每次的原始数据我们不会进行修改,我们修改的都是一个新的数据的副本
        List<User> users = list.stream()
                //过滤,需要我们传递一个断言对象进去,我们自己进行判断,返回结果是一个新的stream
                .filter((user -> user.getAge()>=25))
                .collect(Collectors.toList());
//        System.err.println(users);

        //我想把所有的用户的名字取出来放到一个几个
        ArrayList<String> list2 = new ArrayList<>();
        for (User user: list) {
            String name = user.getName();
            list2.add(name);
        }
//        System.err.println(list2);
        //map 转换,从一个数据类型变成另外一个数据类型(可以还是当前的数据类型),利用我们内部迭代到的对象进行操作得到一个新的结果,然后返回
        List<String> names = list.stream()
//                .map(user -> user.getName())
                .map(User::getName)
                .collect(Collectors.toList());
//        System.err.println(names);

        //弄一些字符串,根据某些操作得到的,比如说查询了数据库等等
        List<String> nameSource = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            nameSource.add("不是好人"+i);
        }
//        System.err.println(nameSource);

        //我想遍历上面的字符串,用每一个字符串作为User的name属性,创建User对象.然后将user对象保存到集合中
        List<User> allUsers = new ArrayList<>();
        for (String name: nameSource) {
            User user = new User();
            user.setName(name);
            allUsers.add(user);
        }
//        System.err.println(allUsers);

        List<User> userList = nameSource.stream()
                .map((name)->{
                    User user = new User();
                    user.setName(name);
                    return user;
                }).collect(Collectors.toList());
//        System.err.println(userList);

//        list.forEach(System.err::println);
//        list.stream().forEach(System.err::println);

        List<User> userList1 = list.stream()
                //peek和foreach是一样的,唯一不同是peek不会结束stream
//                .peek(System.err::println)
                .filter(user -> user.getAge()>27)
                .collect(Collectors.toList());
//        System.err.println(userList1);

        List<User> userList2 = list.stream()
                .map(user -> {
                    user.setName(user.getName()+"----->map");
                    return user;
                })
                .filter(user -> user.getAge()>28)
                .collect(Collectors.toList());
//        System.err.println(userList2);

        boolean allMatch = list.stream()
                //所有的数据都要符合这个断言,有一个不符合就是false
                .allMatch(user -> user.getAge()>22);
//        System.err.println(allMatch);

//所有的数据都要符合这个断言,有一个不符合就是false
//        System.err.println(list.stream()
//                        .allMatch(user -> user.getAge()>18)
//                );
//                 .count 个数
//        System.err.println(list.stream().count());

//                list集合中年龄大于25的有几个
//        System.err.println(list.stream().filter(user -> user.getAge()>25).count());

//        System.err.println(list.stream()
//                //去重,会根据数据的hashcode和equals来进行判断,相同的hashcode和返回true的equals代表相同的对象
//                .distinct()
//                .peek(System.err::println).count()
//            );

        List<Order> orderList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Order order = new Order();
            order.setId(i);
            List<Item> items = new ArrayList<>();
            for (int j = 0; j <5; j++) {
                Item item=new Item();
                item.setName("棒棒糖"+i+"------->"+j);
                item.setPrice(j+2);
                items.add(item);
            }
            order.setItems(items);
            orderList.add(order);
        }

        List<Item> itemList = new ArrayList<>();
        for (Order order:orderList) {
            List<Item> items = order.getItems();
            itemList.addAll(items);
        }
//        System.err.println(itemList);

        List<Item> itemList1 = orderList.stream()
                //我们如果有一个集合,集合中的每个数据内部还有一个集合,我们想把内部的所有的集合的数据保存到一个集合中,可以使用flatmap,这只是一个使用场景
                .flatMap(order -> order.getItems().stream())
                .collect(Collectors.toList());
//        System.err.println(itemList1);
        //模拟分页
//        System.err.println(orderList.stream()
//                //跳过几个数据
//                .skip(5)
//                //只保留几个数据
//                .limit(1)
//                .collect(Collectors.toList())
//        );
        //求最小值,需要我们自己重写一个比较函数,来返回顺序
//        System.err.println(orderList.stream().min((o1, o2) -> o1.getId()-o2.getId()).get());
        //求最大值,需要我们自己重写一个比较函数,来返回顺序
//        System.err.println(orderList.stream().max((o1, o2) -> o1.getId()-o2.getId()).get());

        //遍历数据,第一次传递前面两个数据进来,要求我们返回一个数据,返回的数据也会作为下一次的第一个数据
        Order order = orderList.stream().reduce((order1, order2) -> {
            System.err.println("第一个---->"+order1);
            System.err.println("第二个====>"+order2);
            return order1;//这里返回什么数据,下次就作为第一个数据,可以返回新创建的数据,不一定非得从传过来的参数中取
//            return  new Order();
        }).get();
//        System.err.println("结果--->"+order);
        orderList.stream().parallel();//转成异步,也就是多个线程同时执行
        orderList.parallelStream()//获取异步的stream
                .sequential();//转成同步
    }
}
